package com.paic.mhis.hcpms.agreement.healthcareprovider.web;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.paic.mhis.core.auth.biz.service.UserDetails;
import com.paic.mhis.hcpms.agreement.healthcareprovider.biz.service.AttendantProviderService;
import com.paic.mhis.hcpms.agreement.healthcareprovider.biz.service.ContactService;
import com.paic.mhis.hcpms.agreement.healthcareprovider.dto.ContactDTO;
import com.paic.mhis.hcpms.agreement.healthcareprovider.util.Constants;
import com.paic.mhis.hcpms.agreement.healthcareprovider.util.HttpProcessUtil;
import com.paic.mhis.hcpms.agreement.healthcareprovider.util.ValidatorUtil;
import com.paic.mhis.hcpms.trust.web.vo.IntegrityResponseBean;
import com.paic.mhis.hcpms.trust.web.vo.InterityBlackAddRequestVO;
import com.paic.pafa.app.biz.service.BusinessServiceException;
import com.paic.pafa.appclient.annotation.BizServicesProxy;
import com.paic.pafa.web.BaseRest;

/**
 * 联系信息Controller
 * 
 * @author EX-LUORONG001
 * 
 */
@Controller
public class ContactController extends BaseRest {
	@BizServicesProxy
	private ContactService contactService;

	@BizServicesProxy
	private AttendantProviderService attendantProviderService;

	public static Log log = LogFactory.getLog(ContactController.class);

	public void setContactService(ContactService contactService) {
		this.contactService = contactService;
	}

	/**
	 * 联系信息新增
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/contact/create", method = RequestMethod.POST)
	public Map<String, Object> addContact(HttpServletRequest request) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, Object> contacts_result = null;
		try {
			UserDetails user = (UserDetails) request.getSession().getAttribute(
					"user");
			String str = HttpProcessUtil.readRequestBody(request);
			JSONObject transferJson = JSON.parseObject(str);

			// 机构信息新增时未产生providerId
			if ("".equals(transferJson.get("providerId"))) {
				result.put("state", "0");
				return result;
			}

			// 联系人重复性校验
			contacts_result = attendantProviderService
					.findHospitalProviderOrgDetail(transferJson);
			System.out.println("--------------------------" + contacts_result);
			List contacts = (ArrayList) (contacts_result.get("contact"));

			for (Object contact : contacts) {
				JSONObject json_contact = JSON.parseObject(JSONObject
						.toJSONString(contact));

				if (transferJson.get("workDepCode").equals(
						json_contact.get("workDepCode"))) {
					result.put("state", "0");
					result.put("msg", "科室编码不能重复！");
					return result;
				}

				if (transferJson.get("workDep").equals(
						json_contact.get("workDep"))) {
					result.put("state", "0");
					result.put("msg", "科室不能重复！");
					return result;
				}
			}

			transferJson.put("createby", user.getUsername());
			transferJson.put("updateby", user.getUsername());
			result = this.contactService.addContact(transferJson);

		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 医保人员联系信息新增
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/insurancePer/create", method = RequestMethod.POST)
	public Map<String, Object> addInsurancePer(HttpServletRequest request) {
		Map<String, Object> result = null;
		try {
			UserDetails user = (UserDetails) request.getSession().getAttribute(
					"user");
			String str = HttpProcessUtil.readRequestBody(request);
			JSONArray transferJson = JSON.parseArray(str);

			String username = user.getUsername();
			result = this.contactService
					.addInsurancePer(transferJson, username);

		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	// 批量处理上传科室信息----------------------开始-----------------------add by zjc
	@RequestMapping(value = "/hcp/hRcp/contact/uploadDepartmentExcel", method = RequestMethod.POST)
	@ResponseBody
	public IntegrityResponseBean uploadDepartmentExcel(@ModelAttribute
	InterityBlackAddRequestVO vo, HttpServletRequest request) {
		UserDetails user = (UserDetails) request.getSession().getAttribute(
				"user");
		String providerId = request.getParameter("providerid");

		IntegrityResponseBean returnBean = new IntegrityResponseBean();

		// 1、获取到excel文件列表
		List<MultipartFile> files = getExcelFileList(request);

		// 2、解析excel，返回一个listDTO
		List<ContactDTO> list = this.findExcelContactDTO(files, user);
		// 处理保存
		if (list.isEmpty()) {
			returnBean.setMessage("上传的excel表为空，上传失败");
			return returnBean;
		}

		// 3、listDTO数据空判断,记录空记录数
		int count2 = this.getCheckNullMessage(list);

		// 4、查询数据库中的科室列表，如果有异常则程序退出
		Map<String, Object> resultMap = this.querySqlContactDTO(providerId);
		if (resultMap.get("resultBean") != null) {
			returnBean.setMessage((String) resultMap.get("resultBean"));
			return returnBean;
		}

		// 5、插入excel数据到数据库，并记录重复的数据
		int count1 = ImportExcelData(resultMap, providerId, list, user);

		// 6、返回结果
		printResult(list, count1, count2, returnBean);

		return returnBean;
	}

	private List<MultipartFile> getExcelFileList(HttpServletRequest request) {
		MultipartResolver resolver = new CommonsMultipartResolver(request
				.getSession().getServletContext());
		MultipartHttpServletRequest multiRequest = resolver
				.resolveMultipart(request);
		List<MultipartFile> files = multiRequest.getFiles("file");

		return files;
	}

	private void printResult(List<ContactDTO> list, int count1, int count2,
			IntegrityResponseBean returnBean) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("一共上载").append((list.size() + count2)).append("行数据，")
				.append((list.size() - count1)).append("行数据导入成功；")
				.append(count1).append("行数据因医院科室编码或名称重复而导入失败；").append(count2)
				.append("行数据因医院科室编码、省科室编码、医院科室名称或省科室名称为空而导入失败，");
		if (list.size() <= count1) {
			buffer.append("上载失败");
		} else {
			buffer.append("上载成功");

		}
		returnBean.setMessage(buffer.toString());
	}

	private int ImportExcelData(Map<String, Object> resultMap,
			String providerId, List<ContactDTO> list, UserDetails user) {
		Map<String, Set> codeAndNameMap = this.getCodeAndName(resultMap);
		return this.getResultmessage(list, codeAndNameMap, providerId, user);

	}

	private Map<String, Set> getCodeAndName(Map<String, Object> resultMap) {
		Map<String, Set> codeAndNameMap = new HashMap<String, Set>();
		Set<String> codeSet = new HashSet<String>();
		Set<String> nameSet = new HashSet<String>();
		for (int i = 0; i < ((List) resultMap.get("result")).size(); i++) {
			codeSet.add((String) ((Map) ((List) resultMap.get("result")).get(i))
					.get("workDepCode"));
			nameSet.add((String) ((Map) ((List) resultMap.get("result")).get(i))
					.get("workDep"));
		}
		codeAndNameMap.put("codeSet", codeSet);
		codeAndNameMap.put("nameSet", nameSet);

		return codeAndNameMap;
	}

	private Integer getCheckNullMessage(List<ContactDTO> list) {
		Map<String, Object> checkNull = new HashMap<String, Object>();
		int count2 = 0;
		Iterator<ContactDTO> it = list.iterator();
		while (it.hasNext()) {
			ContactDTO dto = it.next();
			String workDepCode = dto.getWorkDepCode();
			String workDep = dto.getWorkDep();
			String provinceDepartmentCode = dto.getDepartmentNo();
			String provinceDepartmentName = dto.getDepartment();
			if (!StringUtils.hasText(workDepCode)) {
				count2++;
				it.remove();
				continue;
			}
			if (!StringUtils.hasText(workDep)) {
				count2++;
				it.remove();
				continue;
			}
			if (!StringUtils.hasText(provinceDepartmentCode)) {
				count2++;
				it.remove();
				continue;
			}
			if (!StringUtils.hasText(provinceDepartmentName)) {
				count2++;
				it.remove();
				continue;
			}
		}

		return count2;
	}

	private int getResultmessage(List<ContactDTO> list,
			Map<String, Set> codeAndNameMap, String providerId, UserDetails user) {
		int count1 = 0;
		Set<String> codeSet = codeAndNameMap.get("codeSet");
		Set<String> nameSet = codeAndNameMap.get("nameSet");
		for (ContactDTO dto : list) {
			String workDepCode = dto.getWorkDepCode();
			String workDep = dto.getWorkDep();

			if (codeSet.contains(workDepCode) || nameSet.contains(workDep)) {
				count1++;
			} else {
				codeSet.add(workDepCode);
				nameSet.add(workDep);
				// 插入导入数据
				insertImportData(dto, providerId, user);
			}
		}
		return count1;
	}

	private void insertImportData(ContactDTO dto, String providerId,
			UserDetails user) {
		JSONObject transferJson = (JSONObject) JSON.toJSON(dto);
		transferJson.put("providerid", providerId);
		transferJson.put("createby", user.getUsername());
		transferJson.put("updateby", user.getUsername());
		try {
			this.contactService.addContact(transferJson);
			// 上传之前验证excel表中的医院科室编码和医院科室名称是否有重复
		} catch (BusinessServiceException e) {
			HttpProcessUtil.processException(e);
		}
	}

	private Map<String, Object> querySqlContactDTO(String providerId) {

		Map<String, Object> resultMap = new HashMap<String, Object>();
		JSONObject transferJsonForCheck = new JSONObject();
		transferJsonForCheck.put("providerid", providerId);

		try {
			resultMap = contactService.queryContactList(transferJsonForCheck);
		} catch (Exception e) {
			HttpProcessUtil.processException(e);
		}

		if (null == (List) resultMap.get("result")) {
			resultMap.put("resultBean", "未能获取到科室信息列表，上传失败");
		}
		return resultMap;
	}

	private List<ContactDTO> findExcelContactDTO(List<MultipartFile> files,
			UserDetails user) {

		List<ContactDTO> list = new ArrayList<ContactDTO>();

		if (files != null && files.size() > 0) {

			for (MultipartFile file : files) {
				parseExcelToDTO(file, list, user);
			}
		}

		return list;
	}

	private void parseExcelToDTO(MultipartFile file, List<ContactDTO> list,
			UserDetails user) {
		String username = user.getUsername();
		InputStream is = null;

		try {
			is = file.getInputStream();
			HSSFWorkbook wb = new HSSFWorkbook(is);
			HSSFSheet childSheet = wb.getSheetAt(0);
			// readExcel
			readExcelToBean(childSheet, username, list);
		} catch (Exception e) {
			HttpProcessUtil.processException(e);
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
			}
		}
	}

	private void readExcelToBean(HSSFSheet childSheet, String username,
			List<ContactDTO> list) {
		int rowNum = childSheet.getLastRowNum();
		// j=1 跳过head部分
		for (int j = Constants.SECOND_ROW; j <= rowNum; j++) {
			HSSFRow row = childSheet.getRow(j);
			ContactDTO currentBean = this.getContactDTOFromRow(row, username);
			if (null != currentBean) {
				list.add(currentBean);
			}
		}
	}

	private ContactDTO getContactDTOFromRow(HSSFRow row, String opertionUser) {

		if (row == null) {
			return null;
		}

		ContactDTO bean = new ContactDTO();
		int cellNum = row.getLastCellNum(); // 每行有多少列(格)
		for (int k = 0; k < cellNum; k++) {
			if (row.getCell(k) == null) {
				continue;
			}

			String value = row.getCell(k).toString();
			if (!StringUtils.hasText(value)) {
				continue;
			}

			// setBeanFir
			setBeanFir(bean, value, k);

			// setBeansec
			setBeanSec(bean, value, k);
		}
		return bean;
	}

	private void setBeanFir(ContactDTO bean, String value, int k) {

		if (k == 0) { // 医院科室编码
			bean.setWorkDepCode(value);
		}
		if (k == 1) { // 医院科室名称
			bean.setWorkDep(value);
		}
	}

	private void setBeanSec(ContactDTO bean, String value, int k) {
		if (k == 2) { // 省科室编码
			bean.setDepartmentNo(value);
		}
		if (k == 3) { // 省科室名称
			bean.setDepartment(value);
		}
		if (k == 4) { // 科室联系人
			bean.setContacts(value);
		}
		if (k == 5) { // 职务
			bean.setJob(value);
		}
		if (k == 6) { // 联系人手机
			bean.setMoblie(value);
		}
		if (k == 7) { // 联系电话
			bean.setPhone(value);
		}
	}

	// 上传科室信息------------------------------------------结束-------------------------------------------------------
	/**
	 * 联系信息修改
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/contact/update", method = RequestMethod.POST)
	public Map<String, Object> updateContact(HttpServletRequest request) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, Object> contacts_result = null;
		try {
			UserDetails user = (UserDetails) request.getSession().getAttribute(
					"user");
			String str = HttpProcessUtil.readRequestBody(request);
			JSONObject transferJson = JSON.parseObject(str);

			// 机构信息新增时未产生providerId
			if ("".equals(transferJson.get("providerId"))) {
				result.put("state", "0");
				return result;
			}

			// 修改重复性校验
			contacts_result = attendantProviderService
					.findHospitalProviderOrgDetail(transferJson);
			List contacts = (ArrayList) (contacts_result.get("contact"));

			for (Object contact : contacts) {
				JSONObject json_contact = JSON.parseObject(JSONObject
						.toJSONString(contact));
				if ((!transferJson.get("id").equals(json_contact.get("id")))
						&& transferJson.get("workDepCode").equals(
								json_contact.get("workDepCode"))) {
					result.put("state", "0");
					result.put("msg", "科室编码不能重复！");
					return result;
				}
				;
				if ((!transferJson.get("id").equals(json_contact.get("id")))
						&& transferJson.get("workDep").equals(
								json_contact.get("workDep"))) {
					result.put("state", "0");
					result.put("msg", "科室不能重复！");
					return result;
				}
				;
			}

			transferJson.put("updatedby", user.getUsername());
			result = this.contactService.updateContact(transferJson);

		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 联系信息修改
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/insurancePerson/update", method = RequestMethod.POST)
	public Map<String, Object> updateInsruance(HttpServletRequest request) {
		Map<String, Object> result = null;
		try {
			UserDetails user = (UserDetails) request.getSession().getAttribute(
					"user");
			String str = HttpProcessUtil.readRequestBody(request);

			JSONArray transferJson = JSON.parseArray(str);
			// transferJson.put("updatedby", user.getUsername());
			result = this.contactService.updateInsruance(transferJson,
					user.getUsername());

		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 联系信息批量删除
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/contact/delete", method = RequestMethod.POST)
	public Map<String, Object> deleteContact(HttpServletRequest request) {
		UserDetails user = (UserDetails) request.getSession().getAttribute(
				"user");
		Map<String, Object> result = null;
		try {
			String str = HttpProcessUtil.readRequestBody(request);
			JSONObject transferJson = JSON.parseObject(str);
			transferJson.put("updateby", user.getUsername());
			result = this.contactService.deleteContact(transferJson);

		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 联系信息列表查询
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/contact/page")
	public Map<String, Object> queryContactList(HttpServletRequest request) {
		Map<String, Object> result = null;
		UserDetails user = (UserDetails) request.getSession().getAttribute(
				"user");
		try {
			String providerid = request.getParameter("providerid");

			String page = request.getParameter("page");
			String pageSize = request.getParameter("pageSize");
			if (!isEmpty(page) || !isEmpty(pageSize)) {
				if (!ValidatorUtil.isPlusInteger(page)
						|| !ValidatorUtil.isPlusInteger(pageSize)) {
					result = new HashMap<String, Object>();
					HttpProcessUtil.generateExceptionResult(result,
							Constants.STATE_KEY,
							Constants.FAILED_VALIDATE_STATE_VALUE,
							Constants.MSG_KEY,
							Constants.PAGE_VALIDATE_FAILED_MSG);
					return result;
				}
			}
			JSONObject transferJson = new JSONObject();
			transferJson.put("page", page);
			transferJson.put("pageSize", pageSize);
			transferJson.put("providerid", providerid);
			result = this.contactService.queryContactList(transferJson);
			result.put("authority", user.getRegionAuthority());
		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 联系信息列表查询
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/contact/list")
	public Map<String, Object> queryContactListNoPage(HttpServletRequest request) {
		Map<String, Object> result = null;
		UserDetails user = (UserDetails) request.getSession().getAttribute(
				"user");
		try {
			String providerid = request.getParameter("providerid");
			JSONObject transferJson = new JSONObject();
			transferJson.put("providerid", providerid);
			result = this.contactService.queryContactList(transferJson);
			result.put("authority", user.getRegionAuthority());
		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 医保负责人联系信息列表查询
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/insurance/list")
	public Map<String, Object> queryInsuranceList(HttpServletRequest request) {
		Map<String, Object> result = null;
		try {
			String providerid = request.getParameter("providerid");
			String page = request.getParameter("page");
			String pageSize = request.getParameter("pageSize");
			if (!isEmpty(page) || !isEmpty(pageSize)) {
				if (!ValidatorUtil.isPlusInteger(page)
						|| !ValidatorUtil.isPlusInteger(pageSize)) {
					result = new HashMap<String, Object>();
					HttpProcessUtil.generateExceptionResult(result,
							Constants.STATE_KEY,
							Constants.FAILED_VALIDATE_STATE_VALUE,
							Constants.MSG_KEY,
							Constants.PAGE_VALIDATE_FAILED_MSG);
					return result;
				}
			}
			JSONObject transferJson = new JSONObject();
			transferJson.put("page", page);
			transferJson.put("pageSize", pageSize);
			transferJson.put("providerid", providerid);
			result = this.contactService.queryInsuranceList(transferJson);
		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	/**
	 * 联系人信息详情查询
	 * 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/hcp/hcp/contact/show")
	public Map<String, Object> queryContactDetail(HttpServletRequest request) {
		Map<String, Object> result = null;
		UserDetails user = (UserDetails) request.getSession().getAttribute(
				"user");
		try {
			String id = request.getParameter("id");
			JSONObject transferJson = new JSONObject();
			transferJson.put("id", id);
			result = contactService.queryContactDetail(transferJson);
			result.put("authority", user.getRegionAuthority());
		} catch (Exception e) {
			result = HttpProcessUtil.processException(e);
		}
		return result;
	}

	private boolean isEmpty(String param) {
		return param == null || param.equals("");
	}

}
